package com.maybach.core.ao.impl;

import com.maybach.common.BizResult;
import com.maybach.common.enums.PartnerStatusEnum;
import com.maybach.common.enums.user.UserStatusEnum;
import com.maybach.common.model.PartnerDO;
import com.maybach.common.model.UserDO;
import com.maybach.common.query.PartnerQuery;
import com.maybach.common.query.UserQuery;
import com.maybach.component.city.CityData;
import com.maybach.component.city.domain.City;
import com.maybach.component.city.domain.Province;
import com.maybach.core.ao.PartnerAO;
import com.maybach.core.form.partner.PartnerForm;
import com.maybach.core.form.partner.PartnerQueryForm;
import com.maybach.core.manager.PartnerManager;
import com.maybach.core.manager.UserManager;
import com.maybach.core.security.AdminUser;
import com.maybach.core.security.AdminUserUtil;
import com.maybach.dubbo.api.enums.AuditStatusEnum;
import com.maybach.util.AssertUtil;
import com.maybach.util.ImgUrlUtil;
import com.maybach.util.query.support.PageResult;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by houenxun on 16/1/18.
 */
@Component
public class PartnerAOImpl implements PartnerAO {
    @Autowired
    private PartnerManager partnerManager;
    @Autowired
    private UserManager userManager;

    @Override
    public Boolean isAnotherPartnerExist(String certificateCode, Long id) {
        if (StringUtils.isBlank(certificateCode)) {
            return false;
        }
        PartnerQuery query = new PartnerQuery();
        PartnerQuery.Criteria criteria = query.or();
        criteria.andStatusNotEqualTo(PartnerStatusEnum.logical_delete.getCode());
        if (null != id) {
            criteria.andIdNotEqualTo(id);
        }
        criteria.andCertificateCodeEqualTo(certificateCode);
        return partnerManager.countByQuery(query) > 0;
    }

    @Override
    public Long addPartner(PartnerForm partnerForm) {

        PartnerDO partnerDO = this.assemblyPartnerDO(partnerForm);
        partnerDO.setStatus(PartnerStatusEnum.normal.getCode());
        AdminUser adminUser = AdminUserUtil.getUser();
        partnerDO.setCreatorUser(adminUser.getName());
        return partnerManager.insertSelective(partnerDO);
    }

    @Override
    public boolean updatePartner(PartnerForm partnerForm) {
        PartnerDO partnerDO = this.assemblyPartnerDO(partnerForm);
        return partnerManager.updateByPrimaryKeySelective(partnerDO) > 0;
    }

    @Override
    public Boolean isPartnerExist(String certificateCode) {
        return this.getPartnerByCertificateCode(certificateCode) != null;
    }

    @Override
    public PartnerForm getPartnerForm(Long id) {
        PartnerDO partnerDO = this.getPartner(id);
        if (null == partnerDO) {
            return null;
        }
        return this.assemblyPartnerFrom(partnerDO);
    }

    protected PartnerForm assemblyPartnerFrom(PartnerDO partner) {

        PartnerForm partnerForm = new PartnerForm();
        partnerForm.setId(partner.getId());
        partnerForm.setCityId(partner.getCityId());
        partnerForm.setProviceId(partner.getProviceId());
        partnerForm.setCityName(this.getCityName(partner.getProviceId(), partnerForm.getCityId()));
        partnerForm.setAccountBalance(partner.getAccountBalance());
        partnerForm.setCertificateCode(partner.getCertificateCode());
        partnerForm.setCorpLogoImgs(ImgUrlUtil.parseList(partner.getCorpLogoImgs()));
        partnerForm.setContractImgs(ImgUrlUtil.parseList(partner.getContractImgs()));
        partnerForm.setContactsName(partner.getContactsName());
        partnerForm.setContactsPhone(partner.getContactsPhone());
        partnerForm.setCorpDescription(partner.getCorpDescription());
        partnerForm.setCorpName(partner.getCorpName());
        partnerForm.setDetailAddress(partner.getDetailAddress());
        partnerForm.setCredentialsImgs(ImgUrlUtil.parseList(partner.getCredentialsImgs()));
        partnerForm.setLegalCertImgs(ImgUrlUtil.parseList(partner.getLegalCertImgs()));
        partnerForm.setEmail(partner.getEmail());
        partnerForm.setFax(partner.getFax());
        partnerForm.setPartnerMemo(partner.getMemo());
        partnerForm.setStatus(partner.getStatus());
        partnerForm.setType(partner.getType());
        partnerForm.setCreatorUser(partner.getCreatorUser());
        partnerForm.setManager(partner.getManager());
        return partnerForm;
    }

    protected PartnerDO assemblyPartnerDO(PartnerForm partnerForm) {
        AssertUtil.notNull(partnerForm, "partnerForm");
        PartnerDO partnerDO = new PartnerDO();
        partnerDO.setId(partnerForm.getId());
        partnerDO.setCityId(partnerForm.getCityId());
        partnerDO.setProviceId(partnerForm.getProviceId());
        partnerDO.setCityName(this.getCityName(partnerForm.getProviceId(), partnerForm.getCityId()));
        //partnerDO.setAccountBalance(0L);
        partnerDO.setCertificateCode(partnerForm.getCertificateCode());
        partnerDO.setCorpLogoImgs(ImgUrlUtil.mergeList(partnerForm.getCorpLogoImgs()));
        partnerDO.setContractImgs(ImgUrlUtil.mergeList(partnerForm.getContractImgs()));
        partnerDO.setContactsName(partnerForm.getContactsName());
        partnerDO.setContactsPhone(partnerForm.getContactsPhone());
        partnerDO.setCorpDescription(partnerForm.getCorpDescription());
        partnerDO.setCorpName(partnerForm.getCorpName());
        partnerDO.setDetailAddress(partnerForm.getDetailAddress());
        partnerDO.setCredentialsImgs(ImgUrlUtil.mergeList(partnerForm.getCredentialsImgs()));
        partnerDO.setLegalCertImgs(ImgUrlUtil.mergeList(partnerForm.getLegalCertImgs()));
        partnerDO.setEmail(partnerForm.getEmail());
        partnerDO.setFax(partnerForm.getFax());
        partnerDO.setMemo(partnerForm.getPartnerMemo());
        partnerDO.setType(partnerForm.getType());
        partnerDO.setIsVerify(AuditStatusEnum.end.getStatus());
        partnerDO.setManager(partnerForm.getManager());

        return partnerDO;
    }

    @Override
    public PartnerDO getPartnerByCertificateCode(String code) {
        PartnerQuery query = new PartnerQuery();
        query.or().andCertificateCodeEqualTo(code);
        List<PartnerDO> list = partnerManager.selectByQuery(query);
        if (list.size() > 1) {
            throw new RuntimeException("certificateCode=" + code);
        }

        if (list.size() == 1) {
            return list.get(0);
        }

        return null;
    }

    @Override
    public PartnerDO getPartner(Long id) {
        return partnerManager.selectByPrimaryKey(id);
    }

    @Override
    public PageResult<PartnerDO> queryPartner(PartnerQueryForm queryForm) {
        PartnerQuery query = this.assemblyQuery(queryForm);
        return partnerManager.selectByQueryWithPage(query);
    }

    protected PartnerQuery assemblyQuery(PartnerQueryForm queryForm) {
        AssertUtil.notNull(queryForm, "queryForm");
        PartnerQuery query = new PartnerQuery();
        PartnerQuery.Criteria criteria = query.or();
        query.setPageNo(queryForm.getPageNo());
        query.setPageSize(queryForm.getPageSize());

        if (StringUtils.isNotBlank(queryForm.getCorpName())) {
            criteria.andCorpNameLike("%" + queryForm.getCorpName() + "%");
        }
        if (StringUtils.isNotBlank(queryForm.getContactsName())) {
            criteria.andContactsNameLike("%" + queryForm.getContactsName() + "%");
        }
        if (StringUtils.isNotBlank(queryForm.getContactsPhone())) {
            criteria.andContactsPhoneLike("%" + queryForm.getContactsPhone() + "%");
        }
        return query;
    }

    protected String getCityName(Integer proviceId, Integer cityId) {
        if (null != proviceId) {
            Province province = CityData.getProvinceById(proviceId);
            if (null != province) {
                City city = null != cityId ? CityData.getCityById(cityId) : null;
                if (city == null) {
                    return province.getName();
                } else {
                    return province.getName() + city.getName();
                }
            }
        }
        return null;
    }

    @Override
    public BizResult updatePartnerStatus(Long id, Integer status) {
        BizResult result = new BizResult();
        AssertUtil.notNull(id, "id");
        AssertUtil.notNull(status, "status");
        PartnerStatusEnum partnerStatus = PartnerStatusEnum.getStatus(status);
        AssertUtil.notNull(partnerStatus, "partnerStatusEnum");
        PartnerDO partnerDO = partnerManager.selectByPrimaryKey(id);
        if (null == partnerDO) {
            result.setResultMsg("数据不存在");
        } else if (partnerDO.getStatus().equals(status)) {
            result.setResultMsg("数据已更新");
        } else {
            // 禁用时 禁用所用的子用户
            if (partnerStatus.getCode() == PartnerStatusEnum.disable.getCode()) {
                updateUserStatusByPartnerId(id, status);
            }
            partnerDO.setStatus(status);
            partnerManager.updateByPrimaryKeySelective(partnerDO);
        }
        return result;
    }

    private List<Long> updateUserStatusByPartnerId(Long partnerId, int status) {
        AssertUtil.isTrue(null != partnerId && partnerId > 0, "null != partnerId && partnerId > 0 by partnerId=" + partnerId);
        UserQuery query = new UserQuery();
        UserQuery.Criteria criteria = query.or();
        criteria.andStatusIn(Arrays.asList(status, UserStatusEnum.logical_delete.getCode()));
        criteria.andPartnerIdEqualTo(partnerId);
        List<UserDO> list = userManager.selectByQuery(query);
        List<Long> idList = new ArrayList<Long>();
        for (UserDO userDO : list) {
            UserDO u = new UserDO();
            u.setStatus(status);
            u.setId(userDO.getId());
            userManager.updateByPrimaryKeySelective(u);
            idList.add(u.getId());
        }

        return idList;
    }


}
